#ifndef _AMERICO_LINE_H_
#define _AMERICO_LINE_H_

#include "Vector.h"

namespace Intersection
{
	namespace I2D
	{
		template <typename TYPE>
		class Line
		{
		public:
			Vector2<TYPE> point1;
			Vector2<TYPE> point2;
			Vector2<TYPE> direction;
			Vector2<TYPE> normal;

			Line();
			Line(const Vector2<TYPE> &aFirstPoint, const Vector2<TYPE> &aSecondPoint);
			void InitWith2Points(const Vector2<TYPE> &aFirstPoint, const Vector2<TYPE> &aSecondPoint);
			void InitWithPointAndNormal(const Vector2<TYPE> &aPoint, const Vector2<TYPE> &aNormal);
			bool Inside(const Vector2<TYPE> &aPosition) const;

			bool operator==(const Line &aLine) const;
			bool operator!=(const Line &aLine) const;
		};

		template <typename TYPE>
		Line<TYPE>::Line()
		{
		}

		template <typename TYPE>
		Line<TYPE>::Line(const Vector2<TYPE> &aFirstPoint, const Vector2<TYPE> &aSecondPoint)
		{
			InitWith2Points(aFirstPoint, aSecondPoint);
		}

		template <typename TYPE>
		void Line<TYPE>::InitWith2Points(const Vector2<TYPE> &aFirstPoint, const Vector2<TYPE> &aSecondPoint)
		{
			point1 = aFirstPoint;
			point2 = aSecondPoint;
			direction = aSecondPoint - aFirstPoint;
			normal.x = -direction.y;
			normal.y = direction.x;
			if (normal.Length2() != 0)
			{
				normal /= normal.Length();
			}
		}

		template <typename TYPE>
		void Line<TYPE>::InitWithPointAndNormal(const Vector2<TYPE> &aPoint, const Vector2<TYPE> &aNormal)
		{
			point1 = aPoint;
			normal = aNormal;
			direction.x = -normal.y;
			direction.y = normal.x;
			point2 = point1 + direction;
		}

		template <typename TYPE>
		bool Line<TYPE>::Inside(const Vector2<TYPE> &aPosition) const
		{
			if(normal.Dot(aPosition-point1) >= 0)
				return true;
			return false;
		}

		template <typename TYPE>
		bool Line<TYPE>::operator==(const Line<TYPE> & aLine) const
		{
			return ((point1 == aLine.point1) && (direction == aLine.direction));
		}

		template <typename TYPE>
		bool Line<TYPE>::operator!=(const Line<TYPE> & aLine) const
		{
			return (!operator==(aLine));
		}
	};
};

#endif
